package com.zp.self.module.level_4_算法练习.算法.贪心;

public class 力扣_53_最大子数组和 {
    public static void main(String[] args) {
        System.out.println(new 力扣_53_最大子数组和().maxSubArray3(new int[]{-2,1,-3,4,-1,2,1,-5,4}));
        System.out.println(new 力扣_53_最大子数组和().maxSubArray3(new int[]{1}));
        System.out.println(new 力扣_53_最大子数组和().maxSubArray3(new int[]{5,4,-1,7,8}));
    }
    /**
     题目：给你一个整数数组 nums ，请你找出一个具有最大和的连续子数组（子数组最少包含一个元素），返回其最大和。
            子数组 是数组中的一个连续部分。

     示例 1：
     输入：nums = [-2,1,-3,4,-1,2,1,-5,4]
     输出：6
     解释：连续子数组 [4,-1,2,1] 的和最大，为 6 。

     示例 2：
     输入：nums = [1]
     输出：1

     示例 3：
     输入：nums = [5,4,-1,7,8]
     输出：23

     分析：
     1.贪心算法

     边界值 & 注意点：
     1.
     **/
    //贪心算法
    public int maxSubArray(int[] nums) {
        int length = nums.length;
        if(length ==1) return nums[0];
        // 当前最大和:maxSum,  当前和:sum
        // 遍历：前面的和sum <0  ,后面的值加上不就更小吗. 所以sumsum = nums[i] ，对比maxSum ？sum
        int maxSum = nums[0];
        int sum = nums[0];
        for (int i = 1; i < length; i++) {
            if(sum<0)sum = nums[i];
            else sum+=nums[i];
            maxSum = Math.max(maxSum,sum);
        }
        return maxSum;
    }

    //动态规划
    public int maxSubArray2(int[] nums) {
        if(nums.length ==1) return nums[0];
        // 遍历：用当前数组记录每个元素是否应该加上【前面元素的最大值】
        // 前面的和sum <0  ,后面的值加上不就更小吗. 所以nums[i]  = nums[i]
        // 前面的和sum >=0  ,所以nums[i]  = nums[i] + nums[i-1]
        for (int i = 1; i < nums.length; i++)
            if(nums[i-1]>0) nums[i]= nums[i]+nums[i-1] ;
        for (int i = 1; i < nums.length; i++)
            if(nums[i]<nums[i-1]) nums[i] = nums[i-1];
        return nums[nums.length-1];
    }

    //蛮力法
    public int maxSubArray3(int[] nums) {
        int length = nums.length;
        int maxSum = nums[0];
        // 遍历：双重for循环 外层表示:从哪个值为起点，内层表示:加上这个值得多少
        for (int i = 0; i < length; i++){
            int currentSum = nums[i];//表示当前值开始的累积和
            maxSum = Math.max(maxSum,currentSum);
            for (int j = i+1; j < length; j++) {
                currentSum+= nums[j];
                maxSum = Math.max(maxSum,currentSum);
            }
        }
        return maxSum;
    }
}
